package com.hanxiaozhang.juc.atomic;

import java.util.concurrent.atomic.AtomicReference;

/**
 * 〈一句话功能简述〉<br>
 * 〈原子引用类〉
 *
 * @author hanxinghua
 * @create 2024/5/6
 * @since 1.0.0
 */
public class AtomicReferenceNode {


    /*
    AtomicReference是Java中的一个原子类，它的主要作用是提供了一种原子操作的方式来更新对象的引用。
    作用：它通常用于多线程环境下，用来解决并发访问共享对象时，可能出现的竞态条件问题。
    实际开发中用于某个数据模型更新，确保一致性和线程安全，多个线程同时更新只有一个线程能够成功执行，
    其它线程需要等待后继续尝试更新，例如：计算总分(获取答题表分数)并更新到答案表中。
    AtomicReference解决的问题：
    - 原子性更新引用： AtomicReference可以确保在多线程环境下，对对象引用的更新操作是原子的，即要么更新成功，要么失败，
    不存在中间状态。这有助于避免多线程同时修改同一对象引用时可能出现的数据不一致性问题。
    - 解决竞态条件问题： 在多线程编程中，如果多个线程同时尝试更新共享对象的引用，可能会导致不可预测的结果。
    使用AtomicReference可以防止这种情况发生，确保只有一个线程能够成功更新引用。
    - 实现非阻塞算法： AtomicReference可以用于实现非阻塞算法，这些算法通常比基于锁的算法具有更好的性能和可伸缩性，
    特别是在高并发情况下。
    - 并发数据结构的实现： AtomicReference常常用于实现各种并发数据结构，如并发队列、并发映射等，
    以确保对这些数据结构的操作是线程安全的。

     */

    public static void main(String[] args) {

        // 1.创建一个AtomicReference，并赋初始值
        String initialReference = "the initially referenced string";
        AtomicReference<String> atomicReference = new AtomicReference(initialReference);

        // 2.获取值
        String reference = atomicReference.get();
        System.out.println(reference);

        // 3.获取值当前的值，并设置新值
        System.out.println(atomicReference.getAndSet("getAndSet referenced"));
        System.out.println(atomicReference.get());

        // 4.赋值
        atomicReference.set("New object referenced");
        System.out.println(atomicReference.get());

        // 5.比较赋值
        AtomicReference<String> atomicStringReference = new AtomicReference(initialReference);
        String newReference = "new value referenced";

        // 使用CAS更新成功，返回true
        boolean exchanged = atomicStringReference.compareAndSet(initialReference, newReference);
        System.out.println("exchanged: " + exchanged);

        // 使用CAS更新失败，返回false（值存在，不存更新）
        exchanged = atomicStringReference.compareAndSet(initialReference, newReference);
        System.out.println("exchanged: " + exchanged);

    }
}
